<template>
  <div 
    :class="[ 
      'mx-menu-bar',
      options.theme ?? '',
      options.mini ? 'mini' : '',
    ]"
    @focus="onFocus"
    @blur="onBlur"
  >
    <slot name="prefix" />
    
    <div 
      v-if="options.mini"
      ref="menuBarContent"
      class="mx-menu-bar-content"
    >
      <div 
        class="mx-menu-bar-item"
        @click="onItemClick(0, null)"
      >
        <MenuBarIconMenu />
      </div>
    </div>
    <div 
      v-else
      ref="menuBarContent"
      class="mx-menu-bar-content"
    >
      <div 
        v-for="(item, key) in menuItems" 
        :key="key"
        :class="[
          'mx-menu-bar-item',
          item == menuActive ? 'active' : '',
        ]"
        @click="onItemClick(key, item as MenuItem)"
        @mouseenter="onItemEnter(key, item as MenuItem)"
      >
        {{ item.label }}
      </div>
    </div>
    <slot name="suffix" />
  </div>
</template>

<script setup lang="ts">
/**
 * Menu bar component
 */
import { ref, type PropType, onMounted, watch } from 'vue';
import type { MenuBarOptions } from './MenuBar';
import type { ContextMenuInstance, MenuItem } from './ContextMenuDefine';
import { getTop, getLeft } from './ContextMenuUtils';
import ContextMenu from './ContextMenuInstance';
import MenuBarIconMenu from './MenuBarIconMenu.vue';

const props = defineProps({
  /**
   * Menu options
   */
  options: {
    type: Object as PropType<MenuBarOptions>,
    default: null
  }
});

const menuBarContent = ref<HTMLDivElement>();
const menuBarActive = ref(false);
const menuItems = ref<MenuItem[]>([]);
const menuActive = ref<MenuItem|null>(null);

function onFocus() {
  menuBarActive.value = true;
}
function onBlur() {
  menuBarActive.value = false;
}

onMounted(() => {
  (menuItems.value as MenuItem[]) = props.options.items || [];
});
watch(() => props.options, () => {
  (menuItems.value as MenuItem[]) = props.options.items || [];
});

let currentMenu : ContextMenuInstance|null = null;
let currentMenuIndex = -1;

function showNextSubMenu() {
  if (currentMenuIndex < menuItems.value.length - 1)
    currentMenuIndex++;
  else 
    currentMenuIndex = 0;
  showSubMenu(currentMenuIndex, menuItems.value[currentMenuIndex] as MenuItem);
}
function showPrevSubMenu() {
  if (currentMenuIndex > 0)
    currentMenuIndex--;
  else 
    currentMenuIndex = menuItems.value.length - 1;
  showSubMenu(currentMenuIndex, menuItems.value[currentMenuIndex] as MenuItem);
}
function getMenuShowPos(ele: HTMLElement) {
  const showDirection = props.options.barPopDirection ?? 'bl';
  let x = 0; 
  let y = 0;
  if (showDirection.startsWith('b'))
    y = getTop(ele) + ele.offsetHeight;
  else if (showDirection.startsWith('t'))
    y = getTop(ele);
  else 
    y = getTop(ele) + ele.offsetHeight / 2;

  if (showDirection.endsWith('l'))
    x = getLeft(ele);
  else if (showDirection.startsWith('r'))
    x = getLeft(ele) + ele.offsetWidth;
  else 
    x = getLeft(ele) + ele.offsetWidth / 2;

  return { x: x, y: y + 5 }
}
function showSubMenu(index: number, item: MenuItem) {
  currentMenuIndex = index;
  if (!item.children)
    return;
  if (currentMenu) {
    currentMenu.closeMenu();
    currentMenu = null;
    menuBarActive.value = true;
  }
  (menuActive.value as MenuItem) = item;
  const ele = menuBarContent.value?.children[index] as HTMLElement;
  if (ele) {
    const { x, y } = getMenuShowPos(ele);

    currentMenu = ContextMenu.showContextMenu({
      ...props.options,
      items: item.children,
      x,
      y,
      onKeyFocusMoveLeft() {
        showPrevSubMenu();
      },
      onKeyFocusMoveRight() {
        showNextSubMenu();
      },
      onClose() {
        if (menuActive.value == item) {
          menuBarActive.value = false;
          menuActive.value = null;
        }
        if (typeof item.onSubMenuClose === 'function')
          item.onSubMenuClose(undefined);
      },
    });

    if (currentMenu && typeof item.onSubMenuOpen === 'function')
      item.onSubMenuOpen(undefined);
  }
}
function showAllSubMenu() {
  currentMenuIndex = 0;
  const ele = menuBarContent.value as HTMLElement;
  if (ele) {
    const { x, y } = getMenuShowPos(ele);
    currentMenu = ContextMenu.showContextMenu({
      ...props.options,
      x,
      y,
    });
  }
}

function onItemClick(index: number, item: MenuItem|null) {
  if (item) {
    menuBarActive.value = true;
    showSubMenu(index, item);
    if (
      item.onClick && (
      (item.clickableWhenHasChildren === true && item.children && item.children.length > 0)
      || !item.children || item.children.length === 0)
    )
      item.onClick();
  } else {
    showAllSubMenu();
  }
}
function onItemEnter(index: number, item: MenuItem) {
  if (menuBarActive.value) {
    showSubMenu(index, item);
  }
}

</script>

<style lang="scss">
@import './MenuBar.scss';
</style>